﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Othello_Game
{
    /// <summary>
    /// The ActionList class represents all of the actions to be taken upon the player choosing a move
    /// It contains an Array of "Action"'s, all have the same starting point, all have different directions
    /// The static functions of the class help the computer player choose a single move to perform 
    /// from all of the possible ones
    /// </summary>
    public class ActionList
    {
        #region Private Members
        private double alphaValue = 0;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets the actions that this current move will generate on the board
        /// (meaning the enemy's pieces that we turn)  
        /// </summary>
        public Action[] Actions { get; private set; }
        /// <summary>
        /// Gets and Sets the position played at this move by the current player.
        /// </summary>
        public Position Pos { get; private set; }
        /// <summary>
        /// Gets a Othello_Game.BoardState as the game board state at this current move 
        /// </summary>
        public Board BoardState { get; private set; }
        /// <summary>
        /// Gets and sets the Alpha value of this current move
        /// </summary>
        public double AlphaValue 
        {
            get
            {
                if (this.alphaValue == 0)
                {
                    this.alphaValue = (double)Value();
                }

                return this.alphaValue;
            }
            set
            {
                this.alphaValue = value;
            }
        }
        /// <summary>
        /// Gets and sets the Beta value of this current move
        /// </summary>
        public double BetaValue { get; set; }
        /// <summary>
        /// The number of actions in this ActionList
        /// </summary>
        public int Current { get; private set; }
        /// <summary>
        /// This Dictionary holds the values for the position on the board
        /// </summary>
        public IPositionsValues PositionsValues { get; private set; }

        #endregion

        #region Ctor
        /// <summary>
        /// Initializes a new instance of the Othello_Game.ActionList Class.
        /// The ActionList class represent all of the action to be taken uppon choosing a specific move.
        /// </summary>
        /// <param name="pos">The position played at this move by the current player</param>
        /// <param name="board">The game board state at this current move </param>
        public ActionList(Position pos, Board board)
        {
            this.Current = 0;
            this.Pos = new Position(pos.Row, pos.Column);
            this.BoardState = board;

            // Get the Othello_Game.IPositionvalues from the GeneralConsts singelton
            this.PositionsValues = GeneralConsts.Instance.PositionsValues;

            // Initialize the possible actions array, and set the actions as null
            this.Actions = new Action[8];
            for (int i = 0; i < 8; i++)
            {
                Actions[i] = null;
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Adds an Action to this ActionList
        /// </summary>
        /// <param name="action">An action the current move will generate on the game board</param>
        public void AddToList(Action action)
        {
            if (this.Current < 8) 
            {
                Actions[this.Current] = action;
                this.Current++;
            }
        }

        /// <summary>
        /// Calculate the value of this move.
        /// </summary>
        /// <returns>
        /// The value returned is a combined value of the position played
        /// calculate by an attributes list and a weight vector "dot product"
        /// </returns>
        public double Value()
        {
            double[] attrVector = new double[GeneralConsts.Instance.AttributesList.Count];

            for (int i = 0; i < GeneralConsts.Instance.AttributesList.Count; i++)
			{
			    attrVector[i] = GeneralConsts.Instance.AttributesList[i].GetAttributeValues(this);
			}

            return GeneralConsts.Instance.AttributeWeights.DotProduct(attrVector);
        }
        #endregion
    }
}
